這次聊點pattern
的更多用法
最常用的用法是/pattern/command
, 匹配到的該行做操作.
# 針對行的內容有root的做匹配
sed -n '/root/p' /etc/passwd
但sed有個特別的功能行定位
, 就是能快速地跳到某一行開始做匹配操作,也能指定到哪行結束.
用法很簡單, 透過一些簡單範例, 把pattern基本所有組合都列出來.
這次為了方便看出行號, 使用nl
(number lines of files) , 幫忙在每一行前面加上行數
# 只對第10行做輸出
nl /etc/passwd | sed -n '10p'
> 10 news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
# 從第10行開始, 到第20行, 做輸出
nl /etc/passwd | sed -n '10,20p'
> 10 news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
# ...中間忽略
> 20 systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
# 從第10行開始, 到最後一行, 做輸出
# $表示文件最末行
nl /etc/passwd | sed -n '10,$p'
> 10 news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
# ...中間忽略
> 46 systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
-5
這樣的操作# 從第10行開始, 再往後5行, 到第16行結束並輸出
sed -n '10,+5p' /etc/passwd
//
包起來, 2個pattern間用,
做區隔# 從匹配到news的行開始, 直到匹配到www的行做結束
nl /etc/passwd | sed -n '/news/,/www/p'
> 10 news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
> 11 uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
> 12 proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
> 13 www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
# 從第10行開始,直到匹配到www的行做結束
# 一樣是要有逗號做區隔
nl /etc/passwd | sed -n '10,/www/p'
> 10 news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
> 11 uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
> 12 proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
> 13 www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
# 從匹配到news開始,直到第13行做結束
nl /etc/passwd | sed -n '/news/,13p'
> 10 news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
> 11 uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
> 12 proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
> 13 www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
# 不輸出第一行, 本來第一行是root
nl /etc/passwd | sed -n '1!p'
> 2 daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
> 3 bin:x:2:2:bin:/bin:/usr/sbin/nologin
# 第2行~第5行不做輸出
nl /etc/passwd | sed -n '2,5!p'
> 1 root:x:0:0:root:/root:/bin/bash
> 6 games:x:5:60:games:/usr/games:/usr/sbin/nologin
> 7 man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
開始行號~步長command
# 從第1行開始, 每2行做一次匹配輸出
nl /etc/passwd | sed -n '1~2p'
> 1 root:x:0:0:root:/root:/bin/bash
> 3 bin:x:2:2:bin:/bin:/usr/sbin/nologin
> 5 sync:x:4:65534:sync:/bin:/bin/sync
$
,作為行定位符號, $表示最後一行nl /etc/passwd | sed -n '$p'
> 46 systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
其實行號查找就是快速而已, 但實用性質不高
大部分用到都還是字串匹配, 或者直接指定起訖區間.
但sed就是提供不少方便的定位模式做操作.
news假設在第5行, 但後面寫結束是第1行, 這時會怎樣輸出?
nl /etc/passwd | sed -n '/news/,1p'
答案是只輸出匹配到new的行
因為當news被匹配到, 本來就會輸出, 但之後的行, 基本上行號都大於第3行, 這條件等於白設定了.